package model;

import java.io.File;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Observable;

/**
 * Represents a single Conference, with papers submitted and user associated with it.
 * @author Alex
 *
 * Contributors: Owen, Janelle
 */
public class Conference extends Observable implements Serializable{
	private static final long serialVersionUID = 4531422222088018176L;
	private int conferenceId;
	private String conferenceTitle;
	private String conferenceDescription;
	private String conferenceLocation;
	private Map<File, Paper> paperDB;
	private List<User> reviewers;
	private User programChair;
	private List<User> subprogramChairs;
	private List<User> users;

	/**
	 * Creates a Conference.
	 */
	public Conference() {
		reviewers = new ArrayList<User>();
		subprogramChairs = new ArrayList<User>();
		users = new ArrayList<User>();
		paperDB = new HashMap<File, Paper>();
	}

	/**
	 * @return the conferenceId
	 */
	public int getConferenceId() {
		return conferenceId;
	}

	/**
	 * @param conferenceId the conferenceId to set
	 */
	public void setConferenceId(int conferenceId) {
		this.conferenceId = conferenceId;
		update();
	}

	/**
	 * @return the conferenceTitle
	 */
	public String getConferenceTitle() {
		return conferenceTitle;
	}

	/**
	 * @param conferenceTitle the conferenceTitle to set
	 */
	public void setConferenceTitle(String conferenceTitle) {
		this.conferenceTitle = conferenceTitle;
		update();
	}

	/**
	 * @return the conferenceDescription
	 */
	public String getConferenceDescription() {
		return conferenceDescription;
	}

	/**
	 * @param conferenceDescription the conferenceDescription to set
	 */
	public void setConferenceDescription(String conferenceDescription) {
		this.conferenceDescription = conferenceDescription;
		update();
	}

	/**
	 * Adds a reviewer.
	 * @param r - the reviewer to add.
	 */
	public void addReviewer(final User r) {
		if(!reviewers.contains(r))
			reviewers.add(r);
		update();
	}

	/**
	 * Removes a reviewer.
	 * @param r - the reviewer to remove.
	 */
	public void removeReviewer(final User r) {
		reviewers.remove(r);
		update();

	}

	/**
	 * Adds a paper.
	 * @param p - the paper to add.
	 */
	public void addPaper(final Paper p) {
		if(paperDB.containsKey(p.getPaper())) {
			paperDB.put(p.getPaper(), p);
		} else { // new paper
			paperDB.put(p.getPaper(), p);
		}
		update();
	}

	/**
	 * Removes a paper.
	 * @param p - the paper to remove.
	 */
	public void removePaper(final Paper p) {
		paperDB.remove(p.getPaper());
		update();
	}

	/**
	 * @return the conferenceLocation
	 */
	public String getConferenceLocation() {
		return conferenceLocation;
	}
	/**
	 * @return the papers
	 */
	public ArrayList<Paper> getPapers() {
		ArrayList<Paper> p = new ArrayList<Paper>();
		p.addAll(paperDB.values());
		if(p.equals(null))
		{
			return null;
		}
		else{
			return p;
		}	
	}
	/**
	 * @return the reviewers
	 */
	public List<User> getReviewers() {
		return reviewers;
	}
	/**
	 * @return the programChair
	 */
	public User getProgramChair() {
		return programChair;
	}
	/**
	 * @return the subprogramChairs
	 */
	public List<User> getSubprogramChairs() {
		return subprogramChairs;
	}

	/**
	 * Notifies Observers
	 */
	public void update() {
		setChanged();
		notifyObservers("C_" + conferenceId + conferenceTitle + ".ser");
	}

	/**
	 *Adds the sub program chairs to the array
	 * @param u the User
	 */
	public void addSubprogramChairs(User u) {
		subprogramChairs.add(u);
	}

	/**
	 * Adds the user to the array
	 * @param u the user
	 */
	public void addUser(User u) {
		if (!users.contains(u)) {
			users.add(u);
		}
		update();
	}

	/**
	 * Getter for the users
	 * @return the list of users
	 */
	public List<User> getUsers() {
		return users;
	}

	/**
	 * @return the paperDB
	 */
	public Map<File, Paper> getPaperDB() {
		return paperDB;
	}
}
